{-# LANGUAGE RecursiveDo,ExistentialQuantification,StandaloneDeriving,ImpredicativeTypes,
OverloadedStrings,ScopedTypeVariables,TemplateHaskell,GADTs,DeriveGeneric,FlexibleContexts,RankNTypes #-}
module Control.StackNavView(stackNavView,ViewEvent(..)) where
import Reflex.Dom
import Data.Text
import qualified Data.List as L
import Control.Monad.IO.Class
import Control.Monad
import Data.Functor
import Data.Monoid

type StackElement = forall m t. (MonadWidget t m) => m (Event t ViewEvent)
data ViewEvent =  Push StackElement | Pop | None

noneWidget::StackElement
noneWidget = return never

stackNavView::(MonadWidget t m) 
             => [m (Event t ViewEvent)] 
             -> Event t ViewEvent 
             -> m ()
stackNavView initViews stackEv = do
   let lastView = getHeadView initViews 
   rec let megEv = leftmost [eC,stackEv]
       stackListDyn <- foldDyn foldDynFunc initViews megEv
       let eStackList =  updated stackListDyn
       ddd <- widgetHold lastView (getHeadView <$> eStackList)
       let eC =  switchPromptlyDyn ddd
   return ()
 where
   getHeadView listV = if (L.length listV) == 0 then noneWidget else L.head listV
   foldDynFunc Pop (x:xs) = xs
   foldDynFunc None sVal  = sVal
   foldDynFunc (Push  mL) sVal  = mL:sVal